package com.qdxwx.common.upload;

import com.qdxwx.common.config.UploadConfig;
import com.qdxwx.common.utils.DateUtils;
import com.qdxwx.common.utils.TKString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import jakarta.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

/**
 * Qdx NetSchool Platform
 * @author qdxwx
 * @updateTime 2022/5/25
 * @description
 */
public class UploadUtils {

    private static final Logger logger = LoggerFactory.getLogger(UploadUtils.class);

    //普通图片
    public static UploadState saveImageFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadImageFolder);
    }
    //封面 缩略图
    public static UploadState saveCoverFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadCoverFolder);
    }
    //头像
    public static UploadState saveAvatarFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadAvatarFolder);
    }
    //证书
    public static UploadState saveCertFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadCertFolder);
    }
    //广告
    public static UploadState saveAdvertFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadAdvertFolder);
    }

    public static UploadState saveAlbumFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadAlbumFolder);
    }

    //编辑器 内容图片
    public static UploadState saveTinyFile(HttpServletRequest request) {
        return saveImageFile(request, UploadConfig.uploadFolder + "/tiny");
    }

    private static UploadState saveImageFile(HttpServletRequest request, String saveFolder) {
        //String param = request.getParameter("param");
        UploadState uploadState = new UploadState();
        uploadState.setCode(2);
        MultipartHttpServletRequest multipartRequest;
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest) request;
        } else {
            uploadState.setMsg("不支持实例转换！");
            return uploadState;
        }
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
            uploadState.setMsg("未选择上传文件！");
            return uploadState;
        }
        uploadState.setOldPath(multipartFile.getOriginalFilename());
        String ext = getFileExt(uploadState.getOldPath());
        //获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        if (!checkImageExt(ext)) {
            uploadState.setCode(1);
            uploadState.setMsg("文件格式错误，上传失败。");
            return uploadState;
        }
        //最大文件大小
        long maxSize = 4096000;
        uploadState.setFileSize(multipartFile.getSize());
        //检查文件大小
        if (uploadState.getFileSize() > maxSize) {
            uploadState.setCode(1);
            uploadState.setMsg("上传的图片大小不能超过4M。");
            return uploadState;
        }

        uploadState.setSavePath(getSavePath(saveFolder, ext));
        //System.out.println("multipartFile:" + multipartFile.getOriginalFilename());
        //获取文件路径
        //String filePath = UploadUtils.getImageSavePath(param, ext);
        File file = new File(UploadConfig.uploadRoot + uploadState.getSavePath());
        //如果目录不存在，则创建
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                System.out.println("创建目录失败：" + file.getPath());
            }
        }
        try {
            //保存文件
            multipartFile.transferTo(file);
        } catch (Exception e) {
            uploadState.setCode(2);
            uploadState.setMsg("系统繁忙，上传失败");
            logger.error("上传文件失败：{}", e.getMessage());
            return uploadState;
        }
        //返回数据
        uploadState.setCode(0);
        uploadState.setMsg("上传成功！");
        return uploadState;
    }

    public static UploadState saveImageFile(MultipartFile multipartFile, String saveFolder) {
        UploadState uploadState = new UploadState();
        uploadState.setCode(2);
        if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
            uploadState.setMsg("未选择上传文件！");
            return uploadState;
        }
        uploadState.setOldPath(multipartFile.getOriginalFilename());
        String ext = getFileExt(uploadState.getOldPath());
        //获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        if (!checkImageExt(ext)) {
            uploadState.setCode(1);
            uploadState.setMsg("文件格式错误，上传失败。");
            return uploadState;
        }
        //最大文件大小
        long maxSize = 10240000;
        uploadState.setFileSize(multipartFile.getSize());
        //检查文件大小
        if (uploadState.getFileSize() > maxSize) {
            uploadState.setCode(1);
            uploadState.setMsg("上传的图片大小不能超过10M。");
            return uploadState;
        }

        uploadState.setSavePath(getSavePath(saveFolder, ext));
        //System.out.println("multipartFile:" + multipartFile.getOriginalFilename());
        //获取文件路径
        //String filePath = UploadUtils.getImageSavePath(param, ext);
        File file = new File(UploadConfig.uploadRoot + uploadState.getSavePath());
        //如果目录不存在，则创建
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                System.out.println("创建目录失败：" + file.getPath());
            }
        }
        try {
            //保存文件
            multipartFile.transferTo(file);
        } catch (Exception e) {
            uploadState.setCode(2);
            uploadState.setMsg("系统繁忙，上传失败");
            logger.error("上传文件失败：{}", e.getMessage());
            return uploadState;
        }
        //返回数据
        uploadState.setCode(0);
        uploadState.setMsg("上传成功！");
        return uploadState;
    }

    public static UploadState saveFile(HttpServletRequest request) {
        return saveFile(request, UploadConfig.uploadFileFolder);
    }

    public static UploadState saveFile(HttpServletRequest request, String saveFolder) {
        UploadState uploadState = new UploadState();
        uploadState.setCode(2);
        MultipartHttpServletRequest multipartRequest;
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest) request;
        } else {
            uploadState.setMsg("不支持实例转换！");
            return uploadState;
        }
        MultipartFile multipartFile =  multipartRequest.getFile("file");
        if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
            uploadState.setCode(1);
            uploadState.setMsg("未选择上传文件！");
            return uploadState;
        }
        uploadState.setOldPath(multipartFile.getOriginalFilename());
        String ext = getFileExt(uploadState.getOldPath());
        //获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        if (!checkFileExt(ext)) {
            uploadState.setMsg("文件格式错误，上传失败。");
            return uploadState;
        }
        //最大文件大小
        long maxSize = 102400000; //100M
        uploadState.setFileSize(multipartFile.getSize());
        //检查文件大小
        if (uploadState.getFileSize() > maxSize) {
            uploadState.setMsg("上传的文件大小不能超过"+(maxSize/1024000)+"MB。");
            return uploadState;
        }
        uploadState.setSavePath(getSavePath(saveFolder, ext));

        return saveFileStream(multipartFile, uploadState);
    }

    public static UploadState saveVideoFile(HttpServletRequest request) {
        return saveVideoFile(request, UploadConfig.uploadVideoFolder);
    }

    public static UploadState saveVideoFile(HttpServletRequest request, String saveFolder) {
        UploadState uploadState = new UploadState();
        uploadState.setCode(2);
        MultipartHttpServletRequest multipartRequest;
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest) request;
        } else {
            uploadState.setMsg("不支持实例转换！");
            return uploadState;
        }
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
            uploadState.setCode(1);
            uploadState.setMsg("未选择上传文件！");
            return uploadState;
        }
        uploadState.setOldPath(multipartFile.getOriginalFilename());
        String ext = getFileExt(uploadState.getOldPath());
        //获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        if (!checkVideoExt(ext)) {
            uploadState.setMsg("文件格式错误，上传失败。");
            return uploadState;
        }
        //最大文件大小
        long maxSize = 1024000000; //1GB
        uploadState.setFileSize(multipartFile.getSize());
        //检查文件大小
        if (uploadState.getFileSize() > maxSize) {
            uploadState.setMsg("上传的文件大小不能超过"+(maxSize/1024000)+"MB。");
            return uploadState;
        }
        uploadState.setSavePath(getSavePath(saveFolder, ext));

        return saveFileStream(multipartFile, uploadState);
    }

    public static UploadState saveAudioFile(HttpServletRequest request) {
        return saveAudioFile(request, UploadConfig.uploadAudioFolder);
    }

    public static UploadState saveAudioFile(HttpServletRequest request, String saveFolder) {
        UploadState uploadState = new UploadState();
        uploadState.setCode(2);
        MultipartHttpServletRequest multipartRequest;
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest) request;
        } else {
            uploadState.setMsg("不支持实例转换！");
            return uploadState;
        }
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
            uploadState.setMsg("未选择上传文件！");
            return uploadState;
        }
        uploadState.setOldPath(multipartFile.getOriginalFilename());
        String ext = getFileExt(uploadState.getOldPath());
        //获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        if (!checkAudioExt(ext)) {
            uploadState.setMsg("文件格式错误，上传失败。");
            return uploadState;
        }
        //最大文件大小
        long maxSize = 1024000000; //1GB
        uploadState.setFileSize(multipartFile.getSize());
        //检查文件大小
        if (uploadState.getFileSize() > maxSize) {
            uploadState.setMsg("上传的文件大小不能超过"+(maxSize/1024000)+"MB。");
            return uploadState;
        }
        uploadState.setSavePath(getSavePath(saveFolder, ext));

        return saveFileStream(multipartFile, uploadState);

    }

    private static UploadState saveFileStream(
            MultipartFile multipartFile
            , UploadState uploadState) {
        File file = new File(UploadConfig.uploadRoot + uploadState.getSavePath());
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                System.out.println("创建目录失败：" + file.getPath());
            }
        }
        try {
            InputStream ins = multipartFile.getInputStream();
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            uploadState.setMsg("系统繁忙，上传失败");
            return uploadState;
        }
        //返回数据
        uploadState.setCode(0);
        uploadState.setMsg("上传成功！");
        return uploadState;
    }

    /**
     * 获取后缀
     *
     * @param str
     * @return 返回文件后缀
     */
    public static String getFileExt(String str) {
        return str.substring(str.lastIndexOf(".") + 1).toLowerCase();
    }

    public static String getSavePath(String saveFolder) {
        return getSavePath(saveFolder, getFileExt(saveFolder));
    }

    /**
     * 获取文件保存的路径
     *
     * @param saveFolder   保存目录
     * @param ext      文件后缀
     * @return 返回文件路径
     */
    public static String getSavePath(String saveFolder, String ext) {
        return getSavePath(saveFolder, ext, 0);
    }

    public static String getSavePath(String saveFolder, String ext, long userId) {
        StringBuilder filePath = new StringBuilder(saveFolder);
        filePath.append("/");
        filePath.append(DateUtils.toString( "yyyyMM/dd/yyyyMMddHHmmssSSS"));
        filePath.append(TKString.getRanNumber(3));
        if (userId > 0) {
            filePath.append("U").append(userId);
        }
        filePath.append(".").append(ext);
        return filePath.toString();
    }

    public static Boolean checkImageExt(String fileExt) {
        return Arrays.asList(UploadConfig.uploadImageType.split(",")).contains(fileExt);
    }

    public static Boolean checkFileExt(String fileExt) {
        return Arrays.asList(UploadConfig.uploadFileType.split(",")).contains(fileExt);
    }

    public static Boolean checkAudioExt(String fileExt) {
        return Arrays.asList(UploadConfig.uploadAudioType.split(",")).contains(fileExt);
    }

    public static Boolean checkVideoExt(String fileExt) {
        return Arrays.asList(UploadConfig.uploadVideoType.split(",")).contains(fileExt);
    }
}
